package com.demo.interceptor;

import com.demo.annotation.ApiKeyAccessControl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class ApiKeyAccessInterceptor implements HandlerInterceptor {

  private static final ConcurrentHashMap<HandlerMethod, ApiKeyAccessControl.PrivilegeType> CACHE_ACCESS_CONTROL_TYPE = new ConcurrentHashMap<>();

  @Override
  public boolean preHandle(HttpServletRequest req, HttpServletResponse httpServletResponse, Object handler)
      throws Exception {
    // 如果不是映射到方法直接通过，跨域请求会先发送OPTIONS预检请求
    if (!(handler instanceof HandlerMethod)) {
      return true;
    }
    HandlerMethod method = (HandlerMethod) handler;
    ApiKeyAccessControl.PrivilegeType apiKeyAccessControl = getApiKeyAccessControlType(method);
    if (apiKeyAccessControl != null && !ApiKeyAccessControl.PrivilegeType.NONE.equals(apiKeyAccessControl)) {
      // TODO
      log.info("校验apiKey权限");
    }
    return true;
  }

  private ApiKeyAccessControl.PrivilegeType getApiKeyAccessControlType(HandlerMethod method) {
    ApiKeyAccessControl.PrivilegeType type = CACHE_ACCESS_CONTROL_TYPE.get(method);
    if (type != null) {
      return type;
    }
    ApiKeyAccessControl accessControl = method.getMethodAnnotation(ApiKeyAccessControl.class);
    if (accessControl == null) {
      accessControl = AnnotatedElementUtils.findMergedAnnotation(method.getBeanType(), ApiKeyAccessControl.class);
    }
    type = accessControl == null ? ApiKeyAccessControl.PrivilegeType.NONE : accessControl.value();
    CACHE_ACCESS_CONTROL_TYPE.put(method, type);
    return type;
  }

  @Override
  public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
      Exception e) throws Exception {

  }

}
